#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <libpq-fe.h>

#include "error.h"
#include "pgsql.h"

static void db_ClearResult(DB_HANDLER_S *handler)
{
    if (NULL != handler->result)
    {
        PQclear(handler->result);
        handler->result = NULL;
    }

    return;
}

int DB_Connect(DB_HANDLER_S *handler)

{
    const char *conninfo = "host='127.0.0.1' dbname='postgres' user='postgres' password='123456'";

    assert(NULL != handler);

    handler->connection = PQconnectdb(conninfo);
    if (NULL == handler->connection)
    {
        printf("connect db failed !\r\n");
        return ERROR_CONNECTDB_FAILED;
    }

    return ERROR_SUCCESS;
}

int DB_Exec(DB_HANDLER_S *handler, const char *command)
{
    db_ClearResult(handler);
    handler->result = PQexec(handler->connection, command);
    if (NULL == handler->result)
    {
        printf("db exec sql failed ! ERROR : %s\r\n", PQerrorMessage(handler->connection));
        handler->exec_status = PGRES_FATAL_ERROR;
    }
    else
    {
        handler->exec_status = PQresultStatus(handler->result);
    }

    switch (handler->exec_status)
    {
        case PGRES_COMMAND_OK://insert
        {
            handler->affect_rows = strtoul(PQcmdTuples(handler->result), NULL, 0);
            break;
        }
        case PGRES_TUPLES_OK://select
        {
            handler->tuples = (unsigned long) PQntuples(handler->result);
            handler->fields = (unsigned long) PQnfields(handler->result);
            break;
        }
        default:
        {
            printf("db exec sql failed ! ERROR : %s\r\n", PQerrorMessage(handler->connection));
            break;
        }
    }

    return ERROR_SUCCESS;
}

char *DB_Fetch(DB_HANDLER_S *handler, unsigned long tuple, unsigned long field)
{
    return PQgetvalue(handler->result, tuple, field);
}

void DB_Close(DB_HANDLER_S *handler)
{
    db_ClearResult(handler);
    PQfinish(handler->connection);
    handler->connection = NULL;

    return;
}
